package core

import (
	"bufio"
	"context"
	"log"
	"os"
	"time"

	"github.com/fsnotify/fsnotify"
	"github.com/wailsapp/wails/v2/pkg/runtime"
)

const AppEventFileWatch string = "FileWatch"

type FileWatcher struct {
	ctx     *context.Context
	watcher *fsnotify.Watcher
}

func NewFileWatcher() *FileWatcher {
	return &FileWatcher{}
}

// S
func (a *FileWatcher) SetContext(ctx *context.Context) {
	a.ctx = ctx
}

// start fs-notify
func (a *FileWatcher) Init(ctx *context.Context) bool {
	if ctx != nil {
		a.ctx = ctx
	}

	// creatWathcer
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		log.Println("创建监听者失败。")
		log.Println(err)
		return false
	}

	a.watcher = watcher
	go func() {
		for {
			select {
			case event, ok := <-watcher.Events:
				if !ok {
					return
				}

				log.Println("[event] ", event)
				a.fireFileEvent(&event)
			case err, ok := <-watcher.Errors:
				if !ok {
					return
				}
				log.Println("[err]", err)
			}
		}
	}()

	// 读取所有日志
	loadAllDataFromFile(LOG_FILE)

	// err = watcher.Add("/tmp")
	// if err != nil {
	//     log.Fatal(err)
	// }
	return true
}

// 发送文件事件
func (a *FileWatcher) fireFileEvent(event *fsnotify.Event) {
	if a.ctx == nil {
		log.Println("Context is missing!")
		return
	}

	path := event.Name

	msg := ""
	if event.Has(fsnotify.Create) {
		msg = "创建"
	} else if event.Has(fsnotify.Remove) {
		msg = "删除"
	} else if event.Has(fsnotify.Rename) {
		msg = "重命名"
	} else if event.Has(fsnotify.Write) {
		msg = "写入"
	} else if event.Has(fsnotify.Chmod) {
		msg = "修改"
	} else {
		log.Println("事件未识别", event)
		return
	}

	Ring()
	data := FileWatchData{
		Path: path,
		Msg:  msg,
		Time: time.Now().Format("2006-01-02 15:04:05"),
	}

	runtime.EventsEmit(*a.ctx, AppEventFileWatch, data)
	saveToFile(LOG_FILE, &data)
}

// watcher new path
func (a *FileWatcher) WatchPath(path string) bool {
	if a.watcher == nil {
		log.Println("[err] File Watcher is not started! ")
		return false
	}

	err := a.watcher.Add(path)
	if err != nil {
		log.Println("[err]", err)
		return false
	}
	return true
}

func (a *FileWatcher) CloseFileWatcher() {
	a.watcher.Close()
}

func (a *FileWatcher) ReadPaths() []string {
	var paths []string = make([]string, 0)

	file, err := os.Open("path.txt")
	if err != nil {
		log.Println("读取失败", err)
		return paths
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		paths = append(paths, scanner.Text())
	}

	err2 := scanner.Err()
	if err2 != nil {
		log.Println("读取失败2", err)
	}

	return paths
}

// 最后一部分日志
func (a *FileWatcher) LastLogs(max int) []*FileWatchData {
	if max < 1 {
		max = 20
	}

	start := len(DataList) - max
	if start < 0 {
		start = 0
	}

	re := DataList[start:]
	return re
}
